<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
 * 会员类
 * 
 * @author  : $Author: spike $
 * @date    : $Date: 2014-02-25 13:43:37 +0800 (二, 2014-02-25) $
 * @version : $Id: member_model.php 31 2014-02-25 05:43:37Z spike $
 * @rev     : $Revision: 31 $
 */
class Member_model extends CI_Model
{
    private static $_salt = "^salt tastes salty^";

    public function __construct()
    {
        parent::__construct();
    }

    /**
     * 验证用户名格式
     * 
     * @param  [string] 
     * @return [bool]
     */
    public function val_username($username)
    {
        if( ! validate($username, 'EMAIL') )
        {
            $this->set_error("会员名必须是一个邮箱地址。");
            return FALSE;
        }
        return TRUE;
    }

    /**
     * 验证密码格式
     * 
     * @param  [string] 
     * @return [bool]
     */
    public function val_password($password)
    {
        if( ! preg_match('/^[a-zA-Z0-9]{6,20}$/', $password) )
        {
            $this->set_error("密码只能包含英文或数字, 6~20位。");
            return FALSE;
        }
        return TRUE;
    }

    /**
     * [密码加密]
     * @param  [string] $password
     * @return [string]
     */
    protected function _encrypt_password($password)
    {
        return sha1(sha1(strtolower($password).self::$_salt));
    }

    // --------------------------------------------------------------------
    
    /**
     * [获得一个会员的资料]
     * @param  [int]  $member_id
     * @param  [bool] $enable        [是否排除"关闭状态"的会员]
     * @param  [bool] $with_priv     [是否包含会员权限]
     * @param  [bool] $with_role     [是否包含会员角色]
     * @return [array/false]
     */
    public function get_member($member_id, $enable = TRUE)
    {
        $member_id = (int)$member_id;
        if( $member_id<=0)
        {
            $this->set_error("获取会员数据失败：必须指定一个有效的会员id。");
            return FALSE;
        }
        
        $where = array(
            'member_id'  => $member_id,
            'is_delete' => UNDELETED,
        );
        if($enable === TRUE)
        {
            $where['status'] = MEMBER_STATUS_ON;
        }

        $this->load->dao('Member_dao');
        $member = $this->Member_dao->get_one($where);
        if( ! $member)
        {
            $this->set_error("获取会员数据失败：无法找到会员[{$member_id}]。");
            return FALSE;
        }

        return $member;
    }

    // --------------------------------------------------------------------
    
    /**
     * [新增会员]
     * @param  [array]  $params [所有信息的数组]
     * @return [bool]
     */
    public function add_member(Array $params)
    {
        $params = array(
            'username'         => $params['username']         ? xss_clean(trim($params['username']))     : NULL,
            'nickname'         => $params['nickname']         ? xss_clean(trim($params['nickname']))     : NULL,
            'gender'           => $params['gender']           ? strtoupper(xss_clean($params['gender'])) : NULL,
            'mobile'           => $params['mobile']           ? xss_clean($params['mobile'])             : NULL,
            'password'         => $params['password']         ? xss_clean($params['password'])           : NULL,
            'confirm_password' => $params['confirm_password'] ? xss_clean($params['confirm_password'])   : NULL,
            'remark'           => $params['remark']           ? xss_clean($params['remark'])             : NULL,
        );
        
        $member    = array();
        $member_id = NULL;

        // 校验用户名
        if( ! $this->val_username($params['username']) )
        {
            $this->set_error("新增会员失败：".$this->get_error());
            return FALSE;
        }
        // 校验用户名是否存在
        $this->load->dao('Member_dao');
        $count = $this->Member_dao->count(array(
            'username' => $params['username'],
            'is_delete'=> UNDELETED,
        ));
        if( $count > 0 )
        {
            $this->set_error("新增会员失败：会员名已存在");
            return FALSE;
        }
        $member['username'] = $params['username'];

        // 校验昵称
        if( ! validate_length($params['nickname'], 1, 20) )
        {
            $this->set_error("新增会员失败：昵称最少1个字最多20个字[{$params['nickname']}]。");
            return FALSE;
        }
        $this->load->dao('Member_dao');
        $count = $this->Member_dao->count(array(
            'nickname' => $params['nickname'],
            'is_delete'=> UNDELETED,
        ));
        if( $count > 0 )
        {
            $this->set_error("新增会员失败：昵称已存在");
            return FALSE;
        }
        $member['nickname'] = $params['nickname'];

        // 校验性别
        $member_gender = $this->config->item('member_gender');
        if( ! isset($member_gender[$params['gender']]))
        {
            $this->set_error("新增会员失败：未知的性别[{$params['gender']}]。");
            return FALSE;
        }
        $member['gender'] = $params['gender'];

        // 校验手机
        if( ! validate($params['mobile'], 'MOBILE') )
        {
            $this->set_error("新增会员失败：手机格式不符合规范[{$params['mobile']}]。");
            return FALSE;
        }
        $count = $this->Member_dao->count(array(
            'mobile'       => $params['mobile'],
            'is_delete'    => UNDELETED,
        ));
        if( $count > 0 )
        {
            $this->set_error("新增会员失败：手机[{$params['mobile']}]已存在。");
            return FALSE;
        }
        $member['mobile'] = $params['mobile'];

        // 校验密码
        if( ! $this->val_password($params['password']) )
        {
            $this->set_error("新增会员失败：".$this->get_error());
            return FALSE;
        }
        if( $params['password'] !== $params['confirm_password'])
        {
            $this->set_error("新增会员失败：两次输入的密码不一致。");
            return FALSE;
        }
        $member['password'] = $this->_encrypt_password($params['password']);

        // 新建用户
        $member['remark']       = $params['remark'];
        $member['status']       = MEMBER_STATUS_ON;
        $member['is_delete']    = UNDELETED;
        $member['create_admin'] = login_info('admin_id');
        $member['create_time']  = now_str();

        $this->load->dao('Member_dao');
        if( FALSE === $member_id = $this->Member_dao->insert($member))
        {
            $this->set_error("新增会员失败：无法写入数据库。");
            return FALSE;
        }

        return $member_id;
    }

    // --------------------------------------------------------------------
    
    /**
     * [编辑会员]
     * @param  [array]  $params [所有信息的数组]
     * @return [bool]
     */
    public function edit_member($member_id, Array $params)
    {
        $member_id = (int)$member_id;
        if( FALSE === $this->get_member($member_id, TRUE) )
        {
            $this->set_error("编辑会员数据失败：无法找到会员[{$member_id}]。");
            return FALSE;
        }

        $params = array(
            'nickname' => $params['nickname'] ? xss_clean(trim($params['nickname']))     : NULL,
            'gender'   => $params['gender']   ? strtoupper(xss_clean($params['gender'])) : NULL,
            'mobile'   => $params['mobile']   ? xss_clean($params['mobile'])             : NULL,
            'remark'   => $params['remark']   ? xss_clean(trim($params['remark']))       : NULL,
        );
        
        $member = array();

        /* 校验昵称开始 */
        if( isset($params['nickname']) )
        {
            if( ! validate_length($params['nickname'], 1, 20) )
            {
                $this->set_error("编辑会员失败：昵称最少1个字最多20个字[{$params['nickname']}]。");
                return FALSE;
            }
            $this->load->dao('Member_dao');
            $count = $this->Member_dao->count(array(
                'nickname'     => $params['nickname'],
                'is_delete'    => UNDELETED,
                'member_id <>' => $member_id,
            ));
            if( $count > 0 )
            {
                $this->set_error("编辑会员失败：昵称[{$params['nickname']}]已存在");
                return FALSE;
            }
            $member['nickname'] = $params['nickname'];
        }
        /* 校验昵称结束 */
        

        /* 校验性别开始 */
        if( isset($params['gender']) )
        {
            $member_gender = $this->config->item('member_gender');
            if( ! isset($member_gender[$params['gender']]))
            {
                $this->set_error("编辑会员失败：未知的性别[{$params['gender']}]。");
                return FALSE;
            }
            $member['gender'] = $params['gender'];
        }
        /* 校验性别结束 */

        /* 校验手机开始 */
        if( isset($params['gender']) )
        {
            if( ! validate($params['mobile'], 'MOBILE') )
            {
                $this->set_error("编辑会员失败：手机格式不符合规范[{$params['mobile']}]。");
                return FALSE;
            }
            $count = $this->Member_dao->count(array(
                'mobile'       => $params['mobile'],
                'is_delete'    => UNDELETED,
                'member_id <>' => $member_id,
            ));
            if( $count > 0 )
            {
                $this->set_error("编辑会员失败：手机[{$params['mobile']}]已存在。");
                return FALSE;
            }
            $member['mobile'] = $params['mobile'];
        }
        /* 校验手机结束 */

        if( ! $member )
        {
            $this->set_error("编辑会员失败：没有需要编辑的内容。");
            return FALSE;
        }

        // 编辑用户
        $member['remark']       = $params['remark'];
        $member['update_admin'] = login_info('admin_id');
        $member['update_time']  = now_str();

        $where['member_id'] = $member_id; 
        $where['status']    = MEMBER_STATUS_ON; 
        $where['is_delete'] = UNDELETED;

        $this->load->dao('Member_dao');
        $count = $this->Member_dao->update(
            $member,
            $where,
            NULL,
            1
        );
        if( ! ($count > 0) )
        {
            $this->set_error("编辑会员失败：无法写入数据库。");
            return FALSE;
        }

        return TRUE;
    }

    // --------------------------------------------------------------------
    
    /**
     * [生成where条件]
     * @param  [array] $params
     * @return [array]
     */
    private function _member_where($params)
    {
        $where = array(
            'is_delete' => UNDELETED,
        );

        if( ! empty($params['username']) )
        {
            $where['`username` LIKE'] = "%".xss_clean(trim($params['username']))."%";
        }

        if( ! empty($params['nickname']) )
        {
            $where['`nickname` LIKE'] = "%".xss_clean(trim($params['nickname']))."%";
        }

        if( ! empty($params['status']) )
        {
            $member_status = $this->config->item('member_status');
            if( $member_status["{$params['status']}"] )
                $where['status'] = $params['status'];
        }

        if( ! empty($params['gender']) )
        {
            $member_gender = $this->config->item('member_gender');
            if( $member_gender["{$params['gender']}"] )
                $where['gender'] = $params['gender'];
        }

        if( ! empty($params['mobile']) )
        {
             $where['`mobile` LIKE'] = "%".xss_clean(trim($params['mobile']))."%";
        }

        if( ! empty($params['create_time_start']) && strtotime($params['create_time_start']) )
        {
            $where['`create_time` >'] = $params['create_time_start'];
        }

        if( ! empty($params['create_time_end']) && strtotime($params['create_time_end']) )
        {
            $where['`create_time` <'] = $params['create_time_end'];
        }

        if( ! empty($params['update_time_start']) && strtotime($params['update_time_start']) )
        {
            $where['`update_time` >'] = $params['update_time_start'];
        }

        if( ! empty($params['update_time_end']) && strtotime($params['update_time_end']) )
        {
            $where['`update_time` <'] = $params['update_time_end'];
        }
        return $where;
    }

    // --------------------------------------------------------------------

    /**
     * [统计]
     * @param  [array] $params [条件]
     * @return [int]
     */
    public function count_member($params)
    {
        $where = $this->_member_where($params);

        $this->load->dao('Member_dao');
        return $this->Member_dao->count($where);
    }

    // --------------------------------------------------------------------

    /**
     * [分页浏览]
     * @param  [array]  $params         [条件]
     * @param  [int]    $page           [当前页]
     * @param  [int]    $size           [页数，只允许app_config中"pagesize"的值]
     * @param  [string] $orderby        [排序]
     * @param  [bool]   $custom_size    [是否允许自定义分页数量，忽略限制]
     * @return [array]
     */
    public function browse_member($params, $page = NULL, $size = NULL, $orderby = '`member_id` DESC', $custom_size = FALSE)
    {
        $where = $this->_member_where($params);

        switch ($orderby) 
        {
            default:
                    $orderby = '`member_id` DESC';
                break;
        }

        if( $custom_size === TRUE)
        {
            $size  = intval($size) ? intval($size) : 10;
        }
        else
        {
            $pagesize = $this->config->item('pagesize');
            $size     = isset($pagesize[$size]) ? $size : 10;
        }

        $offset   = intval(($page-1)*$size) > 0 ? intval(($page-1)*$size) : 0;
        $total    = 0;

        $this->load->dao('Member_dao');
        $data = $this->Member_dao->get(
            $where, 
            '*', 
            $orderby, 
            $size, 
            $offset, 
            TRUE, 
            $total
        );
        return array(
            'size' => $size,
            'data' => $data,
            'total'=> $total,
        );
    }

    // --------------------------------------------------------------------
    
    /**
     * [改变会员状态]
     * 
     * @param  [int]    $member_id   [编号]
     * @param  [string] $act        [操作类型]
     * @return [bool]
     */
    public function change_member_status($member_id, $act)
    {   
        if( ! $member = $this->get_member($member_id, FALSE))
        {
            $this->set_error("修改会员状态失败：无法找到会员[{$id}]。");
            return FALSE;
        }

        // 初始化数据
        $_status       = NULL;  //修改的状态
        $_allow_status = NULL;  //允许修改的状态
        $_update       = NULL;  //更新的数据
        
        switch (strtolower(trim($act)))
        {
            case 'on':
                    $_status       = MEMBER_STATUS_ON;
                    $_allow_status = array(MEMBER_STATUS_OFF);
                    $_update       = array(
                        'status'       => $_status,
                        'update_time'  => now_str(),
                        'update_admin' => login_info('admin_id'), 
                    );
                break;

            case 'off':
                    $_status       = MEMBER_STATUS_OFF;
                    $_allow_status = array(MEMBER_STATUS_ON);
                    $_update       = array(
                        'status'       => $_status,
                        'update_time'  => now_str(),
                        'update_admin' => login_info('admin_id'), 
                    );
                break;

            default:
                    $this->set_error("修改会员状态失败：未知的操作[{$act}]。");
                    return FALSE;
                break;
        }

        $status      = $this->config->item('member_status');
        $status_name = (string)$status[$_status];

        // 验证状态
        $current_status = (int)$member['status'];
        if($current_status === $_status)
        {
            $this->set_error("修改会员状态失败：无需修改。");
            return FALSE;
        }

        if( $_allow_status && ! in_array($current_status, $_allow_status))
        {
            $this->set_error("修改会员状态失败：不允许被修改为[{$status_name}]状态。");
            return FALSE;
        }

       
        // 只有符合条件才会被修改
        $this->load->dao('Member_dao');
        $affected_row = $this->Member_dao->update_in(
            $_update,
            array('status'    => $_allow_status),
            array('member_id' => $member_id)
        );
        if($affected_row<=0)
        {
            $this->set_error("修改会员状态失败：无法写入数据库。");
            return FALSE;
        }

        return TRUE;
    }
}